#pragma once

#include <string>
#include <vector>
#include <set>
#include <thread>
#include <chrono>
#include <atomic>
#include "BinanceData.h"
#include "BinanceTrade.h"
#include "BinanceAccount.h"
#include "BinanceRestApi.h"
#include "fmtlog.h"

struct Road {
    std::string A;     // "USDT"
    std::string B;     // "BNB"
    std::string C;     // "BTC"
    std::string AB;
    char atb;
    std::string BC;
    char btc;
    std::string CA;
    char cta;
    Road(std::string a, std::string b, std::string c, std::string ab, char ab_, std::string bc, char bc_, std::string ca, char ca_) :
        A(a), B(b), C(c), AB(ab), atb(ab_), BC(bc), btc(bc_), CA(ca), cta(ca_) {}
};

class BinanceTriangle {
public:
    static BinanceTriangle* getInstance(const std::string& apiKey,const std::string& secretKey);
    void checkArbitrage();   // 检查套利机会
    std::string convertToValidQuantity(const std::string& symbol, double amount);

private:
    Order ord;
    std::vector<Road> roads;
    std::set<std::string> roadSet;
    std::set<std::string> allPairs;
    std::vector<std::string> allCoins;
    std::map<std::string,double> minQty;
    //std::vector<std::string> startCoins = { "USDC", "USDT", "TRY", "FDUSD", "BNB", "BTC", "ETH" };
    std::vector<std::string> startCoins = { "USDT","USDC"};
    std::map<std::string,double> initMount = {{"USDT",9},{"USDC",9}};
    bool flag;
    double allVolume;

    std::string apiKey;
    std::string secretKey;
    BinanceData* dataPtr;
    BinanceTrade* tradePtr;
    BinanceAccount* accountPtr;
    BinanceRestApi* restApi;

    static BinanceTriangle* triangle;
    BinanceTriangle(const std::string& apiKey,const std::string& secretKey);
};